package cn.bearspark.idgenerator.provider.service.bo;

import lombok.ToString;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.ConcurrentLinkedQueue;

/**
 * 无序的 id 生成器的业务对象
 *
 * @author f
 */
@ToString(callSuper = true)
public class UnSeqIdGeneratorBO extends IdGeneratorBO {

    /**
     * 提前将无序的 id 集合存放到线程安全的队列中
     */
    private final ConcurrentLinkedQueue<Long> idQueue;

    public UnSeqIdGeneratorBO(int code, long step, long start, long end) {
        super(code, step);

        // 生成有序的 id 集合
        List<Long> idList = new ArrayList<>();
        for (long i = start; i < end; i++) {
            idList.add(i);
        }

        // 打乱有序的 id 集合
        Collections.shuffle(idList);

        // 设置无序的 id 集合
        idQueue = new ConcurrentLinkedQueue<>(idList);
    }

    @Override
    public Long generateId() {
        return idQueue.poll();
    }

    @Override
    public boolean isExhausted(Long currId) {
        // 如果当前获取的 id 为 null，则说明当前 id 段被用尽
        return currId == null;
    }

    @Override
    public long fetchUsedNum() {
        // 已使用的 id 数 = 当前 id 段的 id 数 - 未使用的 id 的数
        return super.getStep() - idQueue.size();
    }
}
